package leeon.mobile.server.bbscache;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import leeon.mobile.server.bbscache.entity.Picture;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesService.OutputEncoding;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.OutputSettings;
import com.google.appengine.api.images.Transform;
import com.google.appengine.api.utils.SystemProperty;

/**
 * 用于缓存图片的servlet
 * 对于请求的图片，先查看数据库是否有，
 * 如果有提取返回，返回一个默认的图片，放入到queue中，等待执行提取任务进行提取
 * @author leeon
 */
public class BBSUploadService {
	
	public static final String PIC_URL = 	
			(SystemProperty.environment.value() == SystemProperty.Environment.Value.Development)?
			"http://localhost:8888/upload":"http://bbsapp.191922.co.cc/upload";
	public static final String PIC_URL_INNER = 
			(SystemProperty.environment.value() == SystemProperty.Environment.Value.Development)?
			"http://localhost:8888/upload":"http://fdubbsapp.appspot.com/upload";
	public static final String PIC_URL_REAL = "http://bbs.fudan.edu.cn/upload";

	public static final long DELETE_PIC_MAX_TIME = 10*24*60*60*1000;//保留10天
	public static final int[] PIC_SIZE = {0, 240, 480, 760, 1020, Integer.MAX_VALUE};
	public static final int[] PIC_QUAL = {   60,  70,  80,  90,   100};
	
	//get pic not found return null;
	public byte[] getPicture(String path) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Picture p = pm.getObjectById(Picture.class, path);
			return p.getBlob()!=null?p.getBlob().getBytes():new byte[0];
		} catch (JDOObjectNotFoundException e) {
			return null;
		} finally {
			pm.close();
		}
	}
	
	public byte[] savePicture(String path) throws IOException {
		InputStream is = Utils.readUrl(PIC_URL_REAL + path);
		ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
		try {
			byte[] b = new byte[1024];
			int i = 0;
			while ((i = is.read(b)) != -1) {
				os.write(b, 0, i);
			}
		} finally {
			is.close();
			os.close();
		}
		
		byte[] b = os.toByteArray();
		Picture p;
		if (b.length > 1024*1024) {
			p = new Picture(path);
			b = new byte[0];
		} else
			p = new Picture(path, new Blob(b));
		
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			pm.makePersistent(p);
		} finally {
			pm.close();
		}
		return b;
	}
	
	public byte[] resize(byte[] blob, int size) {
		//判断目标分辨率
		if (size == 0) return blob;
		int quality = 100;
		for (int i = 1; i < PIC_SIZE.length; i ++) {
			if (size > PIC_SIZE[i-1] && size <= PIC_SIZE[i]) {
				size = PIC_SIZE[i];
				quality = PIC_QUAL[i-1];
				break;
			}
		}
		
		try {
			Image img = ImagesServiceFactory.makeImage(blob);
			if (img.getWidth() <= size) return blob;//比目标分辨率小，那么直接返回
			int h = img.getHeight()*size/img.getWidth();//计算resize后的高度
			
			ImagesService imagesService = ImagesServiceFactory.getImagesService();
			Transform resize = ImagesServiceFactory.makeResize(size, h);
			
			OutputSettings setting = new OutputSettings(OutputEncoding.JPEG);
			setting.setQuality(quality);
			return imagesService.applyTransform(resize, img, setting).getImageData();
		} catch (Exception ex) {
			return blob;
		}
	}
	
	public void deleteExpiredPicture() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Query delete = pm.newQuery("select from leeon.mobile.server.bbscache.entity.Picture " +
					"where create <= createParam parameters java.util.Date createParam");
			delete.deletePersistentAll(new Date(System.currentTimeMillis()-DELETE_PIC_MAX_TIME));
		} finally {
			pm.close();
		}
	}
	
	public void deleteAllPicture() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			Query delete = pm.newQuery("select from leeon.mobile.server.bbscache.entity.Picture");
			delete.deletePersistentAll();
		} finally {
			pm.close();
		}
	}
	
}
